package tool

import (
	"MoSkeleton/framework/core/dto/response"
	"MoSkeleton/framework/core/motypes"
	"fmt"
	mapset "github.com/deckarep/golang-set/v2"
)

type CodeGenItemResp struct {
	response.ModelResp
	SourceTableName string `json:"sourceTableName"`
	TableComment    string `json:"tableComment"`
	SubTableId      uint64 `json:"subTableName,string"`
	SubTableFkName  string `json:"subTableFkName"`
	StructName      string `json:"structName"`
	TplCategory     string `json:"tplCategory"`
	TplWebType      string `json:"tplWebType"`
	PackageName     string `json:"packageName"`
	ModuleName      string `json:"moduleName"`
	BusinessName    string `json:"businessName"`
	FunctionName    string `json:"functionName"`
	FunctionAuthor  string `json:"functionAuthor"`
	GenType         string `json:"genType"`
	GenPath         string `json:"genPath"`
	Options         string `json:"options"`
	CreateBy        string `json:"createBy"`
	UpdateBy        string `json:"updateBy"`
	Remark          string `json:"remark"`
}

type DbTableItemResp struct {
	TableName    string          `json:"tableName" gorm:"column:TABLE_NAME"`
	TableComment string          `json:"tableComment" gorm:"column:TABLE_COMMENT;"`
	CreateTime   *motypes.MoTime `json:"createTime" gorm:"column:CREATE_TIME"`
	UpdateTime   *motypes.MoTime `json:"updateTime" gorm:"column:UPDATE_TIME"`
}

type CodeGenDetailResp struct {
	Info   *GenTableDetailResp   `json:"info,omitempty"`
	Tables []*GenTableDetailResp `json:"tables,omitempty"`
}

type CodeGeneratorResp struct {
	IgnoreTablePrefix bool `json:"ignoreTablePrefix"`
	PermissionPrefix  string
	TableDetailResp   *GenTableDetailResp
	SubTable          *GenTableDetailResp
}

type CodeGeneratorAggregateResp struct {
	CodeGeneratorResps []*CodeGeneratorResp
	ModuleNameSet      mapset.Set[string]
}

func NewCodeGeneratorAggregate(codeGeneratorResps []*CodeGeneratorResp) *CodeGeneratorAggregateResp {
	aggregateResp := &CodeGeneratorAggregateResp{CodeGeneratorResps: codeGeneratorResps}
	aggregateResp.ModuleNameSet = mapset.NewSet[string]()
	for _, codeGeneratorResp := range codeGeneratorResps {
		aggregateResp.ModuleNameSet.Add(codeGeneratorResp.TableDetailResp.ModuleName)
	}
	return aggregateResp
}

type CodeGeneratorModuleAggregateItemResp struct {
	ModuleName string
	//每个模块有多个表， 每张表都有一个唯一的对象
	CodeGenerators []*CodeGeneratorResp
}

func NewCodeGeneratorModuleAggregate(codeGeneratorResps []*CodeGeneratorResp) []*CodeGeneratorModuleAggregateItemResp {
	itemRespMap := make(map[string]*CodeGeneratorModuleAggregateItemResp)
	itemResps := make([]*CodeGeneratorModuleAggregateItemResp, 0)
	moduleTableSet := mapset.NewSet[string]()
	for _, codeGeneratorResp := range codeGeneratorResps {
		itemResp, exists := itemRespMap[codeGeneratorResp.TableDetailResp.ModuleName]
		if !exists {
			itemResp = &CodeGeneratorModuleAggregateItemResp{
				ModuleName:     codeGeneratorResp.TableDetailResp.ModuleName,
				CodeGenerators: make([]*CodeGeneratorResp, 0),
			}
			itemResps = append(itemResps, itemResp)
			itemRespMap[codeGeneratorResp.TableDetailResp.ModuleName] = itemResp
		}
		key := genModuleTableKey(codeGeneratorResp.TableDetailResp.ModuleName, codeGeneratorResp.TableDetailResp.SourceTableName)
		if moduleTableSet.ContainsOne(key) {
			continue
		}
		moduleTableSet.Add(key)
		itemResp.CodeGenerators = append(itemResp.CodeGenerators, codeGeneratorResp)
	}
	return itemResps
}

func genModuleTableKey(module string, table string) string {
	return fmt.Sprintf("%s_%s", module, table)
}
